{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Agent Tools and Run Method Examples\n",
    "\n",
    "This notebook demonstrates two ways to add tools/functions to an agent and shows how to use the `run()` method for standalone agent chat.\n",
    "\n",
    "## Two Methods for Adding Tools:\n",
    "1. **Static Registration**: Pass functions during agent initialization using the `functions` parameter\n",
    "2. **Dynamic Registration**: Pass tools at runtime using the `tools` parameter in the `run()` method\n",
    "\n",
    "Both approaches allow agents to call functions/tools during conversation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Annotated\n",
    "\n",
    "import autogen\n",
    "from autogen import ConversableAgent\n",
    "from autogen.tools import tool\n",
    "\n",
    "# Load LLM configuration\n",
    "llm_config = autogen.LLMConfig.from_json(path=\"OAI_CONFIG_LIST\", cache_seed=42).where(model=[\"gpt-5-nano\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define Sample Tools\n",
    "\n",
    "Let's create some simple tools that our agents can use:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "@tool(description=\"Calculate the square of a number\")\n",
    "def calculate_square(number: Annotated[int, \"The number to square\"]) -> int:\n",
    "    \"\"\"Calculate the square of a number.\"\"\"\n",
    "    result = number**2\n",
    "    print(f\"Calculating square: {number}² = {result}\")\n",
    "    return result\n",
    "\n",
    "\n",
    "@tool(description=\"Get weather information for a city\")\n",
    "def get_weather(city: Annotated[str, \"The city name\"]) -> str:\n",
    "    \"\"\"Get weather information for a city (mock function).\"\"\"\n",
    "    weather_data = {\n",
    "        \"new york\": \"Sunny, 72°F\",\n",
    "        \"london\": \"Cloudy, 15°C\",\n",
    "        \"tokyo\": \"Rainy, 18°C\",\n",
    "        \"paris\": \"Partly cloudy, 20°C\",\n",
    "    }\n",
    "    result = weather_data.get(city.lower(), f\"Weather data not available for {city}\")\n",
    "    print(f\"Weather lookup for {city}: {result}\")\n",
    "    return result\n",
    "\n",
    "\n",
    "@tool(description=\"Count the number of words in a text\")\n",
    "def count_words(text: Annotated[str, \"The text to count words in\"]) -> int:\n",
    "    \"\"\"Count the number of words in a text.\"\"\"\n",
    "    word_count = len(text.split())\n",
    "    print(f\"Counting words in: '{text[:50]}{'...' if len(text) > 50 else ''}' = {word_count} words\")\n",
    "    return word_count"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Method 1: Static Tool Registration\n",
    "\n",
    "Register tools during agent initialization using the `functions` parameter. These tools become permanently available to the agent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create agent with pre-registered functions\n",
    "math_agent = ConversableAgent(\n",
    "    name=\"math_assistant\",\n",
    "    llm_config=llm_config,\n",
    "    system_message=\"You are a helpful math assistant. Use the available tools to help with calculations.\",\n",
    "    functions=[calculate_square, count_words],  # Static registration\n",
    ")\n",
    "\n",
    "print(\"Math agent created with pre-registered tools:\")\n",
    "print(f\"Available tools: {[tool.name for tool in math_agent.tools]}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using the agent with pre-registered tools:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use run() method with pre-registered tools\n",
    "chat_result = math_agent.run(\n",
    "    message=\"Calculate the square of 15 and then count the words in this sentence: 'The quick brown fox jumps over the lazy dog.'\",\n",
    "    max_turns=2,\n",
    ")\n",
    "chat_result.process()\n",
    "\n",
    "print(chat_result.messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Method 2: Dynamic Tool Registration\n",
    "\n",
    "Register tools at runtime using the `tools` parameter in the `run()` method. This allows for flexible tool assignment per conversation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create agent without pre-registered tools\n",
    "flexible_agent = ConversableAgent(\n",
    "    name=\"flexible_assistant\",\n",
    "    llm_config=llm_config,\n",
    "    system_message=\"You are a helpful assistant. Use any available tools to help answer questions.\",\n",
    "    # No functions parameter - tools will be provided dynamically\n",
    ")\n",
    "\n",
    "print(\"Flexible agent created without pre-registered tools:\")\n",
    "print(f\"Available tools: {[tool.name for tool in flexible_agent.tools] if flexible_agent.tools else 'None'}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using the agent with dynamically provided tools:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use run() method with dynamic tool registration\n",
    "chat_result = flexible_agent.run(\n",
    "    message=\"What's the weather like in Tokyo and London?\",\n",
    "    tools=[get_weather],  # Dynamic registration - tools provided at runtime\n",
    "    max_turns=2,\n",
    ")\n",
    "\n",
    "chat_result.process()\n",
    "\n",
    "print(chat_result.messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Another conversation with different tools:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Same agent, different tools for this conversation\n",
    "chat_result = flexible_agent.run(\n",
    "    message=\"Calculate the square of 8 and count words in 'AG2 is an amazing multi-agent framework for Python'\",\n",
    "    tools=[calculate_square, count_words],  # Different tools this time\n",
    "    max_turns=2,\n",
    ")\n",
    "\n",
    "chat_result.process()\n",
    "\n",
    "print(chat_result.messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Combining Both Methods\n",
    "\n",
    "You can combine both approaches - have some tools pre-registered and add more dynamically:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Agent with some pre-registered tools\n",
    "hybrid_agent = ConversableAgent(\n",
    "    name=\"hybrid_assistant\",\n",
    "    llm_config=llm_config,\n",
    "    system_message=\"You are a versatile assistant with both built-in and dynamic capabilities.\",\n",
    "    functions=[calculate_square],  # Pre-registered tool\n",
    ")\n",
    "\n",
    "print(f\"Hybrid agent pre-registered tools: {[tool.name for tool in hybrid_agent.tools]}\")\n",
    "\n",
    "# Add more tools dynamically\n",
    "chat_result = hybrid_agent.run(\n",
    "    message=\"Calculate square of 12, get weather for Paris, and count words in 'Multi-agent systems are the future'\",\n",
    "    tools=[get_weather, count_words],  # Additional dynamic tools\n",
    "    max_turns=3,\n",
    ")\n",
    "\n",
    "chat_result.process()\n",
    "\n",
    "print(chat_result.messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Key Differences Summary\n",
    "\n",
    "| Method | Registration Time | Flexibility | Use Case |\n",
    "|--------|------------------|-------------|----------|\n",
    "| **Static** (`functions` parameter) | Agent initialization | Fixed set of tools | Specialized agents with consistent capabilities |\n",
    "| **Dynamic** (`tools` parameter) | Runtime/per conversation | Flexible tool assignment | General-purpose agents with varying needs |\n",
    "| **Hybrid** | Both | Best of both worlds | Agents with core capabilities + situational tools |\n",
    "\n",
    "### When to use each approach:\n",
    "\n",
    "- **Static Registration**: When you have agents with well-defined roles (e.g., a math agent always needs calculation tools)\n",
    "- **Dynamic Registration**: When you want to reuse the same agent for different types of tasks\n",
    "- **Hybrid**: When you have core tools that are always needed plus situational tools\n",
    "\n",
    "The `run()` method makes it easy to have standalone agent conversations while supporting both tool registration approaches seamlessly."
   ]
  }
 ],
 "metadata": {
  "front_matter": {
   "description": "Agent Quickstart Examples",
   "tags": [
    "agents",
    "tools",
    "quickstart",
    "examples",
    "autogen"
   ]
  },
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
